package com.easy.modules.sysmgr.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.easy.common.dao.DBUtilsHelper;
import com.easy.common.dao.IBaseDao;
import com.easy.common.exception.Exceptions;
import com.easy.common.util.BeanUtils;
import com.easy.common.util.file.FileUtils;
import com.easy.common.web.page.DataGrid;
import com.easy.common.web.page.Msg;
import com.easy.common.web.springmvc.RealPathResolver;
import com.easy.modules.sysmgr.entity.MenuEntity;
import com.easy.modules.sysmgr.service.MenuServiceI;
import com.easy.modules.sysmgr.web.form.MenuForm;

@Service @Transactional
public class MenuServiceImpl implements MenuServiceI {
	
	private static final Logger logger = Logger.getLogger(MenuServiceImpl.class);

	@Autowired
	private DBUtilsHelper dbUtil ;
	
	@Autowired
	private IBaseDao<MenuEntity> basedaoMenu ;
	
	@Autowired
	private RealPathResolver realpath ;
	
	@Override
	public Msg add(MenuForm form) {
		try {
			MenuEntity entity = new MenuEntity() ;
			BeanUtils.copyNotNullProperties(form, entity) ;
			entity.setCreated(new Date()) ;
			if(null != form.getPid()) {
				entity.setMenu(this.basedaoMenu.load(MenuEntity.class, form.getPid())) ;
			}
			
			this.basedaoMenu.add(entity) ;
			this.tree(form, this.realpath.getRequest().getServletContext()) ;
			return new Msg(true, "添加成功!");
		} catch (BeansException e) {
			logger.error(Exceptions.unchecked(e)) ;
			return new Msg(false, "添加失败!");
		}
	}

	@Override
	public Msg addSeri(MenuForm form) {
		
		return null;
	}

	@Override
	public Msg delete(MenuForm form) {
		try {
			MenuEntity t = this.basedaoMenu.load(MenuEntity.class, form.getId());
			del(t);
			this.tree(form, this.realpath.getRequest().getServletContext()) ;
			return new Msg(true, "删除成功!");
		} catch (Exception e) {
			logger.error(Exceptions.unchecked(e)) ;
			return new Msg(false, "删除失败，该模块可能已分配给角色了，请先解除关联！");
		}
	}
	private void del(MenuEntity entity) {
		if (entity.getMenus() != null && entity.getMenus().size() > 0) {
			for (MenuEntity e : entity.getMenus()) {
				del(e);
			}
		}
		this.basedaoMenu.delete(MenuEntity.class, entity.getId());
	}

	@Override
	public MenuForm get(MenuForm form) {
		MenuEntity entity = this.basedaoMenu.load(MenuEntity.class, form.getId());
		BeanUtils.copyNotNullProperties(entity, form);
		if (null != entity.getMenu()) {
			form.setPid(entity.getMenu().getId());
		}
		return form;
	}
	
	@Override
	public Msg edit(MenuForm form) {
		try {
			MenuEntity entity = this.basedaoMenu.load(MenuEntity.class, form.getId());
			BeanUtils.copyNotNullProperties(form, entity);
			entity.setModifyDate(new Date()) ;
			if (null != form.getPid() && !"".equals(form.getPid())) {
				if(!entity.getId().equals(form.getPid())) {
					entity.setMenu(this.basedaoMenu.load(MenuEntity.class, form.getPid()));
				} else {
					return new Msg(false, "操作有误，父模块服务关联自己！");
				}
			}
			this.basedaoMenu.update(entity);
			this.tree(form, this.realpath.getRequest().getServletContext()) ;
			return new Msg(true, "编辑成功!");
		} catch (Exception e) {
			logger.error(Exceptions.unchecked(e)) ;
			return new Msg(false, "编辑失败！");
		}
	}

	@Override
	public DataGrid datagrid(MenuForm from) {
		
		return null;
	}
	
	@Override
	public List<MenuForm> tree(MenuForm form, ServletContext sc) {
		
		List<MenuForm> menu = new ArrayList<MenuForm>();

		String hql = "select t from MenuEntity t where t.menu is null and t.type='R' and t.isShow='0' order by sort desc";
		List<MenuEntity> menus = this.basedaoMenu.list(hql);
		for (MenuEntity entity : menus) {
			MenuForm mf = new MenuForm();
			BeanUtils.copyNotNullProperties(entity, mf);
			mf.setText(entity.getName());
			menu.add(mf);
			exportJsonTree(entity.getMenus(), entity, sc);
		}
		String path = sc.getRealPath("/common/sys_res/") + "/nav-menu-data.json";
		FileUtils.WriteJSON(path, "", menu);
		
		return menu;
	}
	
	private void exportJsonTree(Set<MenuEntity> menus, MenuEntity m, ServletContext sc) {
		List<MenuForm> forms = new ArrayList<MenuForm>();
		if (null != menus && menus.size() > 0) {
			for (MenuEntity entity : menus) {
				if (!"O".equals(entity.getType()) && "0".equals(entity.getIsShow())) {
					forms.add(treeNode(entity));
				}
			}
		}
		String path = sc.getRealPath("/common/sys_res/") + "/nav-" + m.getId() + "-menu-data.json";
		FileUtils.WriteJSON(path, "", forms);
	}
	
	private MenuForm treeNode(MenuEntity entity) {
		MenuForm mf = new MenuForm();
		BeanUtils.copyNotNullProperties(entity, mf);
		mf.setText(entity.getName());

		Map<String, String> attributes = new HashMap<String, String>();
		attributes.put("href", entity.getHref());
		mf.setAttributes(attributes);

		if (null != entity.getMenus() && entity.getMenus().size() > 0) {

			Set<MenuEntity> rs = entity.getMenus();
			List<MenuForm> children = new ArrayList<MenuForm>();
			for (MenuEntity e : rs) {
				if (!"O".equals(e.getType()) && "0".equals(e.getIsShow())) {
					MenuForm tn = treeNode(e);
					BeanUtils.copyNotNullProperties(e, tn, new String[] { "state" });
					tn.setText(e.getName());
					children.add(tn);
				}
			}

			mf.setChildren(children);
		}
		return mf;
	}

	@Override
	public List<MenuForm> treegrid(MenuForm form) {
		List<MenuForm> listform = new ArrayList<MenuForm>() ;
		
		String sql = "select t.* from easy_sysmgr_menu t where t.menu_pid is null and t.type='R' order by sort desc" ;
		
		if(null != form.getId() && !"".equals(form.getId())) {
			sql = "select t.* from easy_sysmgr_menu t where t.id='"+form.getId()+"'" ;
		}
		try {
			List<MenuEntity> entitys = this.dbUtil.getRunner().query(sql, new BeanListHandler<MenuEntity>(MenuEntity.class)) ;
			for (MenuEntity m : entitys) {
				listform.add(treegridNode(m)) ;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return listform;
	}
	
	private MenuForm treegridNode(MenuEntity entity) {
		MenuForm form = new MenuForm() ;
		BeanUtils.copyNotNullProperties(entity, form) ;
		form.setText(entity.getName()) ;
		
		List<MenuForm> children = new ArrayList<MenuForm>();
		
		try {
			List<MenuEntity> entity_child = this.dbUtil.getRunner().query("select t.* from easy_sysmgr_menu t where t.menu_pid='"+entity.getId()+"' order by sort desc", new BeanListHandler<MenuEntity>(MenuEntity.class)) ;
			if(null != entity_child && !entity_child.isEmpty()) {	
				for (MenuEntity m : entity_child) {
					MenuForm form_child = treegridNode(m) ;
					BeanUtils.copyNotNullProperties(m, form_child) ;
					children.add(form_child) ;
				}
				form.setChildren(children) ;
			}
		} catch (BeansException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return form ;
	}
	

	@Override
	public List<MenuForm> combotree(MenuForm form) {
		List<MenuForm> listform = new ArrayList<MenuForm>() ;
		
		String sql = "select t.* from easy_sysmgr_menu t where t.menu_pid is null and t.type='R' and t.isShow=0 order by sort desc" ;
		try {
			List<MenuEntity> entitys = this.dbUtil.getRunner().query(sql, new BeanListHandler<MenuEntity>(MenuEntity.class)) ;
			for (MenuEntity m : entitys) {
				listform.add(combotreeNode(m)) ;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return listform;
	}
	
	private MenuForm combotreeNode(MenuEntity entity) {
		MenuForm form = new MenuForm() ;
		BeanUtils.copyNotNullProperties(entity, form) ;
		form.setText(entity.getName()) ;
		
		List<MenuForm> children = new ArrayList<MenuForm>();
		
		
		try {
			List<MenuEntity> entity_child = this.dbUtil.getRunner().query("select t.* from easy_sysmgr_menu t where t.menu_pid='"+entity.getId()+"' order by sort desc", new BeanListHandler<MenuEntity>(MenuEntity.class)) ;
			if(null != entity_child && !entity_child.isEmpty()) {	//子节点
				form.setState("closed") ;
				for (MenuEntity m : entity_child) {
					MenuForm form_child = combotreeNode(m) ;
					BeanUtils.copyNotNullProperties(m, form_child) ;
					form_child.setText(m.getName()) ;
					children.add(form_child) ;
					
				}
				form.setChildren(children) ;
			}
		} catch (BeansException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return form ;
	}

	@Override
	public Msg sort(MenuForm form) {
		try {
			
			this.dbUtil.getRunner().update("update easy_sysmgr_menu set sort=?, href=? where id=?", new Object[]{form.getSort(), form.getHref(), form.getId()}) ;
			this.tree(form, this.realpath.getRequest().getServletContext()) ;
			return new Msg(true, "修改成功！");
		} catch (Exception e) {
			logger.error(Exceptions.unchecked(e)) ;
			return new Msg(false, "修改失败！");
		}
	}

	@Override
	public Msg isShow(MenuForm form) {
		try {
			this.dbUtil.getRunner().update("update easy_sysmgr_menu set isShow=? where id=?", new Object[]{form.getIsShow(), form.getId()}) ;
			this.tree(form, this.realpath.getRequest().getServletContext()) ;
			return new Msg(true, "修改成功！");
		} catch (Exception e) {
			logger.error(Exceptions.unchecked(e)) ;
			return new Msg(false, "修改失败！");
		}
		
	}

}
